/*
 * Copyright 2007 by LongTop Corporation.
 * Softpack ChuangXin Building 15F, XiaMen, FuJian, PRC 361005
 *
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * LongTop Corporation ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with LongTop.
 * 
 */
package com.mobile.exception;


import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import com.mobile.tools.Message;

/**
 * 系统级异常（开发人员误操作或系统本身产生的异常，如数据库连接失败，空指针错误）的基类，是一个不受控异常基类。
 * 可不用捕捉或传throws方式传递下去。
 * <p/>
 * * 示例如下：<br>
 * <pre>
 * 1)抛出错误(Service)
 * public void getConnection() throws BaseUncheckedException {
 *      ...
 *      throw new BaseUncheckedException("e_login_database_notconnect");
 *      ...
 *      throw new BaseUncheckedException("e_login_connect_failed",new Object[]{"admin","1234"});
 *      ...
 * }
 * 2)捕捉错误(Action)
 * <p/>
 * public login() {
 *      try {
 *           ...
 *      } catch(BaseUncheckedException ex) {
 *          //如果只抛出一种错误，可不加if 条件判断
 *           if (ex.getExceptionKey().equals("e_login_database_notconnect")) {
 *               ...
 *               this.hintErrorMessage(ex.getMessage());
 *           }
 * <p/>
 *           if (ex.getExceptionKey().equals("e_login_connect_failed")) {
 *               ...
 *               this.hintErrorMessage(ex.getMessage());
 *           }
 *      }
 * }
 * </pre>
 *
 * @author Longtop.com
 * @version 1.5
 */
public class BaseUncheckedException extends RuntimeException {

    /**
     * 错误Key，用于唯一标识错误类型。
     * exceptionKey必须在common/applicationMessage.properties中定义。
     */
    private String exceptionKey = null;

    /**
     * 传递给变量的错误值
     */
    private Object[] exceptionValues = null;
    
    /**
     * 错误信息消息文件
     */
    protected static String RESOURCE_FILE_NAME ="config.common.applicationMessage";

    
    /**
     * 根据Key从资源文件转成明文的错误信息
     */
    private String message = null;

    public BaseUncheckedException() {
        super();
    }
    public BaseUncheckedException(Throwable cause) {
        super(cause);
    }
    public BaseUncheckedException(String message, Throwable cause) {
        super(message, cause);
    }


    public BaseUncheckedException(String key) {
        super(Message.getMessage(RESOURCE_FILE_NAME,key, Locale.getDefault()));
        this.exceptionKey = key;
        this.exceptionValues = null;
        //转成明文错误信息
        message = Message.getMessage(RESOURCE_FILE_NAME,key, Locale.getDefault());
    }

    public BaseUncheckedException(String key, String message) {
        super(message);
        this.exceptionKey = key;
        this.message = message;
    }

    public BaseUncheckedException(String key, Object[] args) {
        super(Message.getMessage(RESOURCE_FILE_NAME,key, args,Locale.getDefault()));
        this.exceptionKey = key;
        this.exceptionValues = args;
        //转成明文错误信息
        this.message = Message.getMessage(RESOURCE_FILE_NAME,key, args,Locale.getDefault());
      
    }

    public BaseUncheckedException(Throwable rootCause, String key, Object[] args) {
        super(rootCause);
        this.exceptionKey = key;
        this.exceptionValues = args;
        //转成明文错误信息
        this.message = Message.getMessage(RESOURCE_FILE_NAME,key, args,Locale.getDefault());
    }


    public Object[] getExceptionValues() {
        return exceptionValues;
    }

    public String getExceptionKey() {
        return exceptionKey;
    }

    /**
     * 取得转成明文的错误信息
     *
     * @return String 返回转成明文的错误信息
     */
    public String getMessage() {
        return message == null || message.trim().equals("") ? super.getMessage() : message;
    }

    public String getMessagesString() {
        String[] msgs = this.getMessages();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < msgs.length; i++) {
            sb.append(msgs[i] + "\n");
        }
        return sb.toString();
    }

    public String[] getMessages() {
        Throwable[] throwables = this.getThrowables();
        String[] msgs = new String[throwables.length];
        for (int i = 0; i < throwables.length; i++) {
            msgs[i] = throwables[i].getMessage();
        }
        return msgs;
    }

    public Throwable[] getThrowables() {
        List list = new ArrayList();
        Throwable throwable = this;
        while (throwable != null) {
            list.add(throwable);
            throwable = throwable.getCause();
        }
        return (Throwable[]) list.toArray(new Throwable[list.size()]);
    }
}